package cn.ydxiaoshuai.gis;


import java.math.BigDecimal;

/**
 * Description 墨卡托坐标转换 此方法转换结果最接近腾讯地图
 *             https://lbs.qq.com/service/webService/webServiceGuide/webServiceTranslate
 * ProjectName worktools
 * Created by 小帅丶 on 2023-04-17 16:28.
 * Version 1.0
 */

public class MercatorWGS84ConvertUtil {

    /**
     * @EARTH_CIRCLE_HALF 地球赤道周长的一半
     *                    地球半径6378137米，赤道周长2*PI*r = 2 * 20037508.3427892，
     *                    墨卡托坐标x轴区间[-20037508.3427892,20037508.3427892]
     *                    墨卡托坐标系：展开地球，赤道作为x轴，向东为x轴正方，本初子午线作为y轴，向北为y轴正方向。
     **/
    private static BigDecimal EARTH_CIRCLE_HALF = new BigDecimal(20037508.34);

    /**
     * @EARTH_RADIUS 地球半径
     **/
    private static BigDecimal EARTH_RADIUS = new BigDecimal(6378137.0);

    /**
     * @STRAIGHT_ANGLE 平角 180°
     **/
    private static BigDecimal STRAIGHT_ANGLE = new BigDecimal(180);

    private static CoordinateBean  mercatorToWGS84(BigDecimal mercatorLngX,
                                                   BigDecimal  mercatorLatY){
        CoordinateBean coord = new CoordinateBean();
        BigDecimal coordLng = mercatorLngX.divide(EARTH_CIRCLE_HALF,BigDecimal.ROUND_CEILING).setScale(4,BigDecimal.ROUND_HALF_EVEN)
                .multiply(STRAIGHT_ANGLE).setScale(4,BigDecimal.ROUND_HALF_EVEN);
        BigDecimal coordLat = mercatorLatY.divide(EARTH_CIRCLE_HALF,BigDecimal.ROUND_CEILING).setScale(4,BigDecimal.ROUND_HALF_EVEN)
                .multiply(STRAIGHT_ANGLE).setScale(4,BigDecimal.ROUND_HALF_EVEN);
        Double tempLat = STRAIGHT_ANGLE.doubleValue() /
                Math.PI * (2 * Math.atan(Math.exp(coordLat.doubleValue() * Math.PI /
                STRAIGHT_ANGLE.doubleValue())) - Math.PI / 2);
        coordLat =  new BigDecimal(tempLat).setScale(4,BigDecimal.ROUND_HALF_EVEN);
        coord.setCoordLngX(coordLng);
        coord.setCoordLatY(coordLat);
        System.out.println(coordLng.doubleValue() + "===" + coordLat);
        return coord;
    }

    private static CoordinateBean WGS84ToMercator(BigDecimal lng,
                                                  BigDecimal lat){
        CoordinateBean coord = new CoordinateBean();
        BigDecimal PI = new BigDecimal(Math.PI);
        BigDecimal coordLng = lng.multiply(PI)
                .divide(STRAIGHT_ANGLE,BigDecimal.ROUND_CEILING)
                .multiply(EARTH_RADIUS)
                .setScale(4,BigDecimal.ROUND_HALF_EVEN);
        BigDecimal tempParam = lat.multiply(PI).divide(STRAIGHT_ANGLE,BigDecimal.ROUND_CEILING)
                .setScale(4,BigDecimal.ROUND_HALF_EVEN);
        Double tempLat = EARTH_RADIUS.doubleValue()
                / 2 * Math.log((1.0 + Math.sin(tempParam.doubleValue()))
                / (1.0 - Math.sin(tempParam.doubleValue())));
        BigDecimal coordLat = new BigDecimal(tempLat).setScale(4,BigDecimal.ROUND_HALF_EVEN);
        coord.setCoordLngX(coordLng);
        coord.setCoordLatY(coordLat);
        System.out.println(coordLng.toPlainString() + "===" + coordLat.toPlainString());
        return coord;
    }


    public static void main(String[] args) {
        BigDecimal coordLng = new BigDecimal(39419429.2936);
        BigDecimal coordLat = new BigDecimal(4452052.1597);
        //代码转换 39.996===89.7629 腾讯地图 转换 39.99303 === 89.740407
        mercatorToWGS84(coordLat,coordLng);
    }
}
